package com.uniflow.service;

import com.uniflow.common.PageResult;
import com.uniflow.entity.ProcessDefinition;
import com.uniflow.entity.ProcessInstance;
import com.uniflow.entity.Task;
import org.flowable.engine.*;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.identitylink.api.IdentityLinkType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 工作流服务类
 */
@Service
@Transactional
public class WorkflowService {
    
    private static final Logger logger = LoggerFactory.getLogger(WorkflowService.class);
    
    @Autowired
    private RepositoryService repositoryService;
    
    @Autowired
    private RuntimeService runtimeService;
    
    @Autowired
    private TaskService taskService;
    
    @Autowired
    private HistoryService historyService;
    
    @Autowired
    private ManagementService managementService;
    
    @Autowired
    private IdentityService identityService;
    
    @Autowired
    private UniflowFormService formService;
    
    @Autowired
    private FormDataService formDataService;
    
    @Autowired
    @Lazy
    private TaskCenterService taskCenterService;
    
    @Autowired
    private AuditLogService auditLogService;
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private com.uniflow.util.AuditLogHelper auditLogHelper;
    
    // ==================== 流程定义管理 ====================
    
    /**
     * 部署流程定义
     */
    public String deployProcess(String name, MultipartFile file) {
        try {
            String fileName = file.getOriginalFilename();
            InputStream inputStream = file.getInputStream();
            
            Deployment deployment = repositoryService.createDeployment()
                    .name(name)
                    .addInputStream(fileName, inputStream)
                    .deploy();
            
            return deployment.getId();
        } catch (Exception e) {
            throw new RuntimeException("部署流程失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 部署流程定义（通过XML内容）
     */
    public String deployProcessByXml(String name, String xmlContent) {
        try {
            Deployment deployment = repositoryService.createDeployment()
                    .name(name)
                    .addString(name + ".bpmn20.xml", xmlContent)
                    .deploy();
            
            return deployment.getId();
        } catch (Exception e) {
            throw new RuntimeException("部署流程失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 从classpath部署流程定义
     */
    public String deployProcessFromClasspath(String resourcePath, String name) {
        try {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(resourcePath);
            if (inputStream == null) {
                throw new RuntimeException("找不到资源文件: " + resourcePath);
            }
            
            Deployment deployment = repositoryService.createDeployment()
                    .name(name)
                    .addInputStream(resourcePath, inputStream)
                    .deploy();
            
            return deployment.getId();
        } catch (Exception e) {
            throw new RuntimeException("部署流程失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 分页查询流程定义列表
     */
    public PageResult<ProcessDefinition> getProcessDefinitionList(int pageNum, int pageSize, String keyword, String category) {
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery()
                .latestVersion()
                .orderByProcessDefinitionKey().asc();
        
        if (StringUtils.hasText(keyword)) {
            query.processDefinitionNameLike("%" + keyword + "%");
        }
        
        if (StringUtils.hasText(category)) {
            query.processDefinitionCategory(category);
        }
        
        int offset = (pageNum - 1) * pageSize;
        List<org.flowable.engine.repository.ProcessDefinition> flowableDefinitions = 
                query.listPage(offset, pageSize);
        
        long total = query.count();
        
        List<ProcessDefinition> definitions = flowableDefinitions.stream()
                .map(this::convertToProcessDefinition)
                .collect(Collectors.toList());
        
        return new PageResult<ProcessDefinition>(pageNum, pageSize, total, definitions);
    }
    
    /**
     * 根据ID查询流程定义
     */
    public ProcessDefinition getProcessDefinitionById(String id) {
        org.flowable.engine.repository.ProcessDefinition flowableDefinition = 
                repositoryService.getProcessDefinition(id);
        
        if (flowableDefinition == null) {
            return null;
        }
        
        return convertToProcessDefinition(flowableDefinition);
    }
    
    /**
     * 获取流程定义XML内容
     */
    public String getProcessDefinitionXml(String processDefinitionId) {
        try {
            InputStream inputStream = repositoryService.getResourceAsStream(
                    repositoryService.getProcessDefinition(processDefinitionId).getDeploymentId(),
                    repositoryService.getProcessDefinition(processDefinitionId).getResourceName());
            
            Scanner scanner = new Scanner(inputStream, "UTF-8").useDelimiter("\\A");
            return scanner.hasNext() ? scanner.next() : "";
        } catch (Exception e) {
            throw new RuntimeException("获取流程定义XML失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 删除流程定义
     */
    public void deleteProcessDefinition(String deploymentId, boolean cascade) {
        repositoryService.deleteDeployment(deploymentId, cascade);
    }
    
    /**
     * 激活/挂起流程定义
     */
    public void activateOrSuspendProcessDefinition(String processDefinitionId, boolean activate) {
        if (activate) {
            repositoryService.activateProcessDefinitionById(processDefinitionId);
        } else {
            repositoryService.suspendProcessDefinitionById(processDefinitionId);
        }
    }
    
    // ==================== 流程实例管理 ====================
    
    /**
     * 启动流程实例（返回ProcessInstance对象）
     */
    public ProcessInstance startProcess(String processDefinitionKey, String businessKey, 
                                        Map<String, Object> variables, String startUserId) {
        try {
            // 设置启动用户
            identityService.setAuthenticatedUserId(startUserId);
            
            org.flowable.engine.runtime.ProcessInstance flowableInstance;
            if (StringUtils.hasText(businessKey)) {
                flowableInstance = runtimeService.startProcessInstanceByKey(
                        processDefinitionKey, businessKey, variables);
            } else {
                flowableInstance = runtimeService.startProcessInstanceByKey(
                        processDefinitionKey, variables);
            }
            
            ProcessInstance processInstance = convertToProcessInstance(flowableInstance);
            
            // 记录审计日志
            auditLogHelper.recordWorkflowOperation("PROCESS_START", flowableInstance.getId(), 
                                                   processDefinitionKey, startUserId, 
                                                   "启动流程实例: " + processDefinitionKey);
            
            // 创建流程启动任务记录
            createProcessStartTask(flowableInstance, startUserId, variables);
            
            return processInstance;
        } catch (Exception e) {
            // 记录失败的审计日志
            auditLogHelper.recordApiOperation("PROCESS_START", "PROCESS_INSTANCE", null, 
                                              startUserId, "启动流程失败: " + e.getMessage(), false);
            throw new RuntimeException("启动流程失败: " + e.getMessage(), e);
        } finally {
            identityService.setAuthenticatedUserId(null);
        }
    }
    
    /**
     * 启动流程实例（返回流程实例ID）
     */
    public String startProcessInstance(String processDefinitionKey, String businessKey, 
                                      Map<String, Object> variables, String startUserId) {
        ProcessInstance processInstance = startProcess(processDefinitionKey, businessKey, variables, startUserId);
        return processInstance.getId();
    }
    
    /**
     * 分页查询流程实例列表
     */
    public PageResult<ProcessInstance> getProcessInstanceList(int pageNum, int pageSize, 
                                                              String processDefinitionKey, String businessKey, 
                                                              String startUserId, Boolean finished) {
        ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
                .orderByStartTime().desc();
        
        if (StringUtils.hasText(processDefinitionKey)) {
            query.processDefinitionKey(processDefinitionKey);
        }
        
        if (StringUtils.hasText(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        
        if (StringUtils.hasText(startUserId)) {
            query.startedBy(startUserId);
        }
        
        if (finished != null && finished) {
            // 查询已结束的流程实例需要使用历史服务
            return getHistoricProcessInstanceList(pageNum, pageSize, processDefinitionKey, businessKey, startUserId);
        }
        
        int offset = (pageNum - 1) * pageSize;
        List<org.flowable.engine.runtime.ProcessInstance> flowableInstances = 
                query.listPage(offset, pageSize);
        
        long total = query.count();
        
        List<ProcessInstance> instances = flowableInstances.stream()
                .map(this::convertToProcessInstance)
                .collect(Collectors.toList());
        
        return new PageResult<ProcessInstance>(pageNum, pageSize, total, instances);
    }
    
    /**
     * 查询历史流程实例
     */
    private PageResult<ProcessInstance> getHistoricProcessInstanceList(int pageNum, int pageSize, 
                                                                       String processDefinitionKey, String businessKey, 
                                                                       String startUserId) {
        HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery()
                .finished()
                .orderByProcessInstanceEndTime().desc();
        
        if (StringUtils.hasText(processDefinitionKey)) {
            query.processDefinitionKey(processDefinitionKey);
        }
        
        if (StringUtils.hasText(businessKey)) {
            query.processInstanceBusinessKey(businessKey);
        }
        
        if (StringUtils.hasText(startUserId)) {
            query.startedBy(startUserId);
        }
        
        int offset = (pageNum - 1) * pageSize;
        List<HistoricProcessInstance> historicInstances = query.listPage(offset, pageSize);
        
        long total = query.count();
        
        List<ProcessInstance> instances = historicInstances.stream()
                .map(historic -> convertToProcessInstance(historic))
                .collect(Collectors.toList());
        
        return new PageResult<ProcessInstance>(pageNum, pageSize, total, instances);
    }
    
    /**
     * 根据ID查询流程实例
     */
    public ProcessInstance getProcessInstanceById(String processInstanceId) {
        org.flowable.engine.runtime.ProcessInstance flowableInstance = 
                runtimeService.createProcessInstanceQuery()
                        .processInstanceId(processInstanceId)
                        .singleResult();
        
        if (flowableInstance != null) {
            return convertToProcessInstance(flowableInstance);
        }
        
        // 如果运行时没有找到，查询历史
        HistoricProcessInstance historicInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        
        if (historicInstance != null) {
            return convertToProcessInstance(historicInstance);
        }
        
        return null;
    }
    
    /**
     * 删除流程实例
     */
    public void deleteProcessInstance(String processInstanceId, String deleteReason) {
        runtimeService.deleteProcessInstance(processInstanceId, deleteReason);
    }
    
    /**
     * 激活/挂起流程实例
     */
    public void activateOrSuspendProcessInstance(String processInstanceId, boolean activate) {
        if (activate) {
            runtimeService.activateProcessInstanceById(processInstanceId);
        } else {
            runtimeService.suspendProcessInstanceById(processInstanceId);
        }
    }
    
    // ==================== 任务管理 ====================
    
    /**
     * 分页查询任务列表
     */
    public PageResult<Task> getTaskList(int pageNum, int pageSize, String assignee, 
                                        String processDefinitionKey, String processInstanceId, 
                                        String taskName, Boolean finished) {
        if (finished != null && finished) {
            return getHistoricTaskList(pageNum, pageSize, assignee, processDefinitionKey, processInstanceId, taskName);
        }
        
        TaskQuery query = taskService.createTaskQuery()
                .orderByTaskCreateTime().desc();
        
        if (StringUtils.hasText(assignee)) {
            query.taskAssignee(assignee);
        }
        
        if (StringUtils.hasText(processDefinitionKey)) {
            query.processDefinitionKey(processDefinitionKey);
        }
        
        if (StringUtils.hasText(processInstanceId)) {
            query.processInstanceId(processInstanceId);
        }
        
        if (StringUtils.hasText(taskName)) {
            query.taskNameLike("%" + taskName + "%");
        }
        
        int offset = (pageNum - 1) * pageSize;
        List<org.flowable.task.api.Task> flowableTasks = query.listPage(offset, pageSize);
        
        long total = query.count();
        
        List<Task> tasks = flowableTasks.stream()
                .map(this::convertToTask)
                .collect(Collectors.toList());
        
        return new PageResult<Task>(pageNum, pageSize, total, tasks);
    }
    
    /**
     * 查询历史任务
     */
    private PageResult<Task> getHistoricTaskList(int pageNum, int pageSize, String assignee, 
                                                 String processDefinitionKey, String processInstanceId, 
                                                 String taskName) {
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery()
                .finished()
                .orderByHistoricTaskInstanceEndTime().desc();
        
        if (StringUtils.hasText(assignee)) {
            query.taskAssignee(assignee);
        }
        
        if (StringUtils.hasText(processDefinitionKey)) {
            query.processDefinitionKey(processDefinitionKey);
        }
        
        if (StringUtils.hasText(processInstanceId)) {
            query.processInstanceId(processInstanceId);
        }
        
        if (StringUtils.hasText(taskName)) {
            query.taskNameLike("%" + taskName + "%");
        }
        
        int offset = (pageNum - 1) * pageSize;
        List<HistoricTaskInstance> historicTasks = query.listPage(offset, pageSize);
        
        long total = query.count();
        
        List<Task> tasks = historicTasks.stream()
                .map(this::convertToTask)
                .collect(Collectors.toList());
        
        return new PageResult<Task>(pageNum, pageSize, total, tasks);
    }
    
    /**
     * 完成任务
     */
    public void completeTask(String taskId, Map<String, Object> variables, String comment) {
        // 添加评论
        if (StringUtils.hasText(comment)) {
            taskService.addComment(taskId, null, comment);
        }
        
        // 处理表单数据
        processFormDataOnTaskComplete(taskId, variables);
        
        // 完成任务
        taskService.complete(taskId, variables);
    }
    
    /**
     * 认领任务
     */
    public void claimTask(String taskId, String userId) {
        taskService.claim(taskId, userId);
    }
    
    /**
     * 委派任务
     */
    public void delegateTask(String taskId, String userId) {
        taskService.delegateTask(taskId, userId);
    }
    
    /**
     * 转办任务
     */
    public void assignTask(String taskId, String userId) {
        taskService.setAssignee(taskId, userId);
    }
    
    /**
     * 审批任务（同意）
     */
    public void approveTask(String taskId, String comment, Map<String, Object> variables) {
        // 添加审批意见
        if (StringUtils.hasText(comment)) {
            taskService.addComment(taskId, null, comment);
        }
        
        // 设置审批结果变量
        if (variables == null) {
            variables = new HashMap<>();
        }
        variables.put("approved", true);
        variables.put("approvalResult", "approved");
        
        // 处理表单数据
        processFormDataOnTaskComplete(taskId, variables);
        
        // 完成任务
        taskService.complete(taskId, variables);
    }
    
    /**
     * 拒绝任务（驳回）
     */
    public void rejectTask(String taskId, String reason, Map<String, Object> variables) {
        // 添加驳回理由
        if (StringUtils.hasText(reason)) {
            taskService.addComment(taskId, null, "驳回理由: " + reason);
        }
        
        // 设置驳回结果变量
        if (variables == null) {
            variables = new HashMap<>();
        }
        variables.put("approved", false);
        variables.put("approvalResult", "rejected");
        variables.put("rejectReason", reason);
        
        // 处理表单数据
        processFormDataOnTaskComplete(taskId, variables);
        
        // 完成任务
        taskService.complete(taskId, variables);
    }
    
    /**
     * 转移任务（转办给其他人）
     */
    public void transferTask(String taskId, String targetUserId, String reason) {
        // 添加转办理由
        if (StringUtils.hasText(reason)) {
            taskService.addComment(taskId, null, "转办理由: " + reason);
        }
        
        // 转办任务
        taskService.setAssignee(taskId, targetUserId);
    }
    
    // ==================== 辅助方法 ====================
    
    /**
     * 转换Flowable流程定义为自定义实体
     */
    private ProcessDefinition convertToProcessDefinition(org.flowable.engine.repository.ProcessDefinition flowableDefinition) {
        ProcessDefinition definition = new ProcessDefinition();
        definition.setId(flowableDefinition.getId());
        definition.setKey(flowableDefinition.getKey());
        definition.setName(flowableDefinition.getName());
        definition.setDescription(flowableDefinition.getDescription());
        definition.setVersion(flowableDefinition.getVersion());
        definition.setCategory(flowableDefinition.getCategory());
        definition.setDeploymentId(flowableDefinition.getDeploymentId());
        definition.setResourceName(flowableDefinition.getResourceName());
        definition.setDiagramResourceName(flowableDefinition.getDiagramResourceName());
        definition.setSuspended(flowableDefinition.isSuspended());
        definition.setTenantId(flowableDefinition.getTenantId());
        definition.setHasStartFormKey(flowableDefinition.hasStartFormKey());
        definition.setHasGraphicalNotation(flowableDefinition.hasGraphicalNotation());
        
        return definition;
    }
    
    /**
     * 转换Flowable流程实例为自定义实体
     */
    private ProcessInstance convertToProcessInstance(org.flowable.engine.runtime.ProcessInstance flowableInstance) {
        ProcessInstance instance = new ProcessInstance();
        instance.setId(flowableInstance.getId());
        instance.setProcessDefinitionId(flowableInstance.getProcessDefinitionId());
        instance.setProcessDefinitionKey(flowableInstance.getProcessDefinitionKey());
        instance.setProcessDefinitionName(flowableInstance.getProcessDefinitionName());
        instance.setProcessDefinitionVersion(flowableInstance.getProcessDefinitionVersion());
        instance.setDeploymentId(flowableInstance.getDeploymentId());
        instance.setBusinessKey(flowableInstance.getBusinessKey());
        instance.setName(flowableInstance.getName());
        instance.setDescription(flowableInstance.getDescription());
        instance.setStartUserId(flowableInstance.getStartUserId());
        instance.setTenantId(flowableInstance.getTenantId());
        instance.setSuspended(flowableInstance.isSuspended());
        instance.setEnded(flowableInstance.isEnded());
        
        if (flowableInstance.getStartTime() != null) {
            instance.setStartTime(LocalDateTime.ofInstant(
                    flowableInstance.getStartTime().toInstant(), ZoneId.systemDefault()));
        }
        
        instance.setStatus(flowableInstance.isSuspended() ? "suspended" : 
                          flowableInstance.isEnded() ? "completed" : "running");
        
        return instance;
    }
    
    /**
     * 转换历史流程实例为自定义实体
     */
    private ProcessInstance convertToProcessInstance(org.flowable.engine.history.HistoricProcessInstance historicInstance) {
        ProcessInstance instance = new ProcessInstance();
        instance.setId(historicInstance.getId());
        instance.setProcessDefinitionId(historicInstance.getProcessDefinitionId());
        instance.setProcessDefinitionKey(historicInstance.getProcessDefinitionKey());
        instance.setProcessDefinitionName(historicInstance.getProcessDefinitionName());
        instance.setProcessDefinitionVersion(historicInstance.getProcessDefinitionVersion());
        instance.setDeploymentId(historicInstance.getDeploymentId());
        instance.setBusinessKey(historicInstance.getBusinessKey());
        instance.setName(historicInstance.getName());
        instance.setDescription(historicInstance.getDescription());
        instance.setStartUserId(historicInstance.getStartUserId());
        instance.setTenantId(historicInstance.getTenantId());
        instance.setEnded(historicInstance.getEndTime() != null);
        instance.setDeleteReason(historicInstance.getDeleteReason());
        
        if (historicInstance.getStartTime() != null) {
            instance.setStartTime(LocalDateTime.ofInstant(
                    historicInstance.getStartTime().toInstant(), ZoneId.systemDefault()));
        }
        
        if (historicInstance.getEndTime() != null) {
            instance.setEndTime(LocalDateTime.ofInstant(
                    historicInstance.getEndTime().toInstant(), ZoneId.systemDefault()));
        }
        
        if (historicInstance.getDurationInMillis() != null) {
            instance.setDurationInMillis(historicInstance.getDurationInMillis());
        }
        
        instance.setStatus(historicInstance.getEndTime() != null ? "completed" : "running");
        
        return instance;
    }
    
    /**
     * 转换Flowable任务为自定义实体
     */
    private Task convertToTask(org.flowable.task.api.Task flowableTask) {
        Task task = new Task();
        task.setId(flowableTask.getId());
        task.setName(flowableTask.getName());
        task.setDescription(flowableTask.getDescription());
        task.setAssignee(flowableTask.getAssignee());
        task.setOwner(flowableTask.getOwner());
        task.setProcessInstanceId(flowableTask.getProcessInstanceId());
        task.setProcessDefinitionId(flowableTask.getProcessDefinitionId());
        task.setTaskDefinitionKey(flowableTask.getTaskDefinitionKey());
        task.setExecutionId(flowableTask.getExecutionId());
        task.setParentTaskId(flowableTask.getParentTaskId());
        task.setFormKey(flowableTask.getFormKey());
        task.setCategory(flowableTask.getCategory());
        task.setTenantId(flowableTask.getTenantId());
        task.setPriority(flowableTask.getPriority());
        task.setSuspended(flowableTask.isSuspended());
        
        if (flowableTask.getCreateTime() != null) {
            task.setCreateTime(LocalDateTime.ofInstant(
                    flowableTask.getCreateTime().toInstant(), ZoneId.systemDefault()));
        }
        
        if (flowableTask.getDueDate() != null) {
            task.setDueDate(LocalDateTime.ofInstant(
                    flowableTask.getDueDate().toInstant(), ZoneId.systemDefault()));
        }
        
        if (flowableTask.getClaimTime() != null) {
            task.setClaimTime(LocalDateTime.ofInstant(
                    flowableTask.getClaimTime().toInstant(), ZoneId.systemDefault()));
        }
        
        // 获取候选人信息
        try {
            List<IdentityLink> identityLinks = taskService.getIdentityLinksForTask(flowableTask.getId());
            List<String> candidateUsers = new ArrayList<>();
            List<String> candidateGroups = new ArrayList<>();
            
            for (IdentityLink identityLink : identityLinks) {
                if (IdentityLinkType.CANDIDATE.equals(identityLink.getType())) {
                    if (identityLink.getUserId() != null) {
                        candidateUsers.add(identityLink.getUserId());
                    }
                    if (identityLink.getGroupId() != null) {
                        candidateGroups.add(identityLink.getGroupId());
                    }
                }
            }
            
            task.setCandidateUsers(candidateUsers);
            task.setCandidateGroups(candidateGroups);
        } catch (Exception e) {
            logger.warn("获取任务候选人信息失败: {}", e.getMessage());
        }
        
        task.setStatus(flowableTask.getAssignee() != null ? "assigned" : "created");
        
        return task;
    }
    
    /**
     * 转换历史任务为自定义实体
     */
    private Task convertToTask(org.flowable.task.api.history.HistoricTaskInstance historicTask) {
        Task task = new Task();
        task.setId(historicTask.getId());
        task.setName(historicTask.getName());
        task.setDescription(historicTask.getDescription());
        task.setAssignee(historicTask.getAssignee());
        task.setOwner(historicTask.getOwner());
        task.setProcessInstanceId(historicTask.getProcessInstanceId());
        task.setProcessDefinitionId(historicTask.getProcessDefinitionId());
        task.setTaskDefinitionKey(historicTask.getTaskDefinitionKey());
        task.setExecutionId(historicTask.getExecutionId());
        task.setParentTaskId(historicTask.getParentTaskId());
        task.setFormKey(historicTask.getFormKey());
        task.setCategory(historicTask.getCategory());
        task.setTenantId(historicTask.getTenantId());
        task.setPriority(historicTask.getPriority());
        
        if (historicTask.getCreateTime() != null) {
            task.setCreateTime(LocalDateTime.ofInstant(
                    historicTask.getCreateTime().toInstant(), ZoneId.systemDefault()));
        }
        
        if (historicTask.getDueDate() != null) {
            task.setDueDate(LocalDateTime.ofInstant(
                    historicTask.getDueDate().toInstant(), ZoneId.systemDefault()));
        }
        
        if (historicTask.getClaimTime() != null) {
            task.setClaimTime(LocalDateTime.ofInstant(
                    historicTask.getClaimTime().toInstant(), ZoneId.systemDefault()));
        }
        
        if (historicTask.getDurationInMillis() != null) {
            task.setDurationInMillis(historicTask.getDurationInMillis());
        }
        
        task.setStatus("completed");
        
        return task;
    }
    

    
    /**
     * 创建流程启动任务记录
     */
    private void createProcessStartTask(org.flowable.engine.runtime.ProcessInstance processInstance, 
                                       String startUserId, Map<String, Object> variables) {
        try {
            com.uniflow.entity.TaskCenter taskCenter = new com.uniflow.entity.TaskCenter();
            taskCenter.setTitle("流程启动: " + processInstance.getProcessDefinitionName());
            taskCenter.setType("WORKFLOW");
            taskCenter.setCategory("PROCESS_START");
            taskCenter.setStatus("COMPLETED");
            taskCenter.setPriority(3); // 普通优先级
            taskCenter.setAssigneeId(startUserId);
            taskCenter.setCreatedBy(startUserId);
            taskCenter.setBusinessType("PROCESS_INSTANCE");
            taskCenter.setBusinessKey(processInstance.getBusinessKey());
            taskCenter.setProcessInstanceId(processInstance.getId());
            taskCenter.setDescription("流程实例启动: " + processInstance.getProcessDefinitionKey());
            taskCenter.setCreatedAt(LocalDateTime.now());
            taskCenter.setUpdatedAt(LocalDateTime.now());
            taskCenter.setCompletedTime(LocalDateTime.now());
            
            // 处理表单绑定信息
            if (variables != null) {
                // 从variables中获取表单ID和表单数据ID
                Object formIdObj = variables.get("formId");
                Object formDataIdObj = variables.get("formDataId");
                
                if (formIdObj != null) {
                    taskCenter.setFormId(formIdObj.toString());
                }
                
                if (formDataIdObj != null) {
                    taskCenter.setFormDataId(formDataIdObj.toString());
                }
            }
            
            // 获取用户信息
            if (StringUtils.hasText(startUserId)) {
                com.uniflow.entity.User user = userService.getUserById(startUserId);
                if (user != null) {
                    taskCenter.setAssigneeName(user.getDisplayName());
                    taskCenter.setCreatedByName(user.getDisplayName());
                }
            }
            
            taskCenterService.createTask(taskCenter);
        } catch (Exception e) {
            // 任务记录创建失败不应影响主业务流程
            System.err.println("创建流程启动任务记录失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理任务完成时的表单数据
     */
    private void processFormDataOnTaskComplete(String taskId, Map<String, Object> variables) {
        try {
            // 查找与任务关联的表单数据
            com.uniflow.entity.FormData formData = formDataService.getFormDataByTaskId(taskId);
            
            if (formData != null) {
                    // 更新表单数据状态为已完成
                    formData.setStatus("completed");
                    formData.setUpdatedAt(LocalDateTime.now());
                    
                    // 如果variables中包含表单字段数据，更新到表单数据中
                    if (variables != null && !variables.isEmpty()) {
                        // 将variables中的表单字段数据合并到formData的data字段中
                        Map<String, Object> formDataMap = formData.getData();
                        if (formDataMap == null) {
                            formDataMap = new HashMap<>();
                        }
                        
                        // 过滤出表单相关的变量（排除系统变量）
                        Map<String, Object> formVariables = variables.entrySet().stream()
                            .filter(entry -> !isSystemVariable(entry.getKey()))
                            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                        
                        formDataMap.putAll(formVariables);
                        formData.setData(formDataMap);
                    }
                    
                // 保存更新后的表单数据
                formDataService.updateFormData(formData);
            }
        } catch (Exception e) {
            // 表单数据处理失败不应影响主业务流程
            System.err.println("处理任务完成时的表单数据失败: " + e.getMessage());
        }
    }
    
    /**
     * 判断是否为系统变量
     */
    private boolean isSystemVariable(String variableName) {
        // 系统变量列表，这些变量不应该保存到表单数据中
        Set<String> systemVariables = new HashSet<>(Arrays.asList(
            "approved", "approvalResult", "rejectReason", 
            "assignee", "candidateUsers", "candidateGroups",
            "dueDate", "priority", "category", "formKey",
            "taskDefinitionKey", "processDefinitionId", "processInstanceId"
        ));
        
        return systemVariables.contains(variableName) || 
               variableName.startsWith("_") || // 以下划线开头的变量通常是系统变量
               variableName.startsWith("sys_"); // 以sys_开头的变量是系统变量
    }
    
    /**
     * 获取工作流统计信息
     */
    public Map<String, Object> getWorkflowStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 流程定义统计
        long totalProcessDefinitions = repositoryService.createProcessDefinitionQuery().count();
        long activeProcessDefinitions = repositoryService.createProcessDefinitionQuery().active().count();
        
        // 流程实例统计
        long totalProcessInstances = historyService.createHistoricProcessInstanceQuery().count();
        long runningProcessInstances = runtimeService.createProcessInstanceQuery().count();
        long finishedProcessInstances = historyService.createHistoricProcessInstanceQuery().finished().count();
        
        // 任务统计
        long totalTasks = historyService.createHistoricTaskInstanceQuery().count();
        long activeTasks = taskService.createTaskQuery().count();
        long finishedTasks = historyService.createHistoricTaskInstanceQuery().finished().count();
        
        statistics.put("totalProcessDefinitions", totalProcessDefinitions);
        statistics.put("activeProcessDefinitions", activeProcessDefinitions);
        statistics.put("totalProcessInstances", totalProcessInstances);
        statistics.put("runningProcessInstances", runningProcessInstances);
        statistics.put("finishedProcessInstances", finishedProcessInstances);
        statistics.put("totalTasks", totalTasks);
        statistics.put("activeTasks", activeTasks);
        statistics.put("finishedTasks", finishedTasks);
        
        return statistics;
    }
    
    /**
     * 获取工作流分类列表
     */
    public List<String> getWorkflowCategories() {
        List<org.flowable.engine.repository.ProcessDefinition> processDefinitions = 
            repositoryService.createProcessDefinitionQuery().list();
        
        return processDefinitions.stream()
            .map(org.flowable.engine.repository.ProcessDefinition::getCategory)
            .filter(Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
    }
    
    /**
     * 验证工作流定义
     */
    public Map<String, Object> validateWorkflow(List<Map<String, Object>> nodes, List<Map<String, Object>> connections) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        List<String> warnings = new ArrayList<>();
        
        // 基本验证
        if (nodes == null || nodes.isEmpty()) {
            errors.add("工作流必须包含至少一个节点");
        } else {
            // 检查开始节点
            boolean hasStartNode = nodes.stream().anyMatch(node -> "start".equals(node.get("type")));
            if (!hasStartNode) {
                errors.add("工作流必须包含一个开始节点");
            }
            
            // 检查结束节点
            boolean hasEndNode = nodes.stream().anyMatch(node -> "end".equals(node.get("type")));
            if (!hasEndNode) {
                warnings.add("建议添加结束节点");
            }
        }
        
        // 连接验证
        if (connections != null && !connections.isEmpty()) {
            for (Map<String, Object> connection : connections) {
                String source = (String) connection.get("source");
                String target = (String) connection.get("target");
                
                if (source == null || target == null) {
                    errors.add("连接必须指定源节点和目标节点");
                }
            }
        }
        
        result.put("valid", errors.isEmpty());
        result.put("errors", errors);
        result.put("warnings", warnings);
        
        return result;
    }
    
    /**
     * 导入工作流
     */
    public String importWorkflow(MultipartFile file) {
        try {
            String filename = file.getOriginalFilename();
            if (filename == null || !filename.endsWith(".bpmn") && !filename.endsWith(".xml")) {
                throw new RuntimeException("只支持.bpmn或.xml格式的文件");
            }
            
            String name = filename.substring(0, filename.lastIndexOf('.'));
            return deployProcess(name, file);
        } catch (Exception e) {
            logger.error("导入工作流失败", e);
            throw new RuntimeException("导入工作流失败: " + e.getMessage());
        }
    }
    
    /**
     * 复制工作流
     */
    public String copyWorkflow(String processDefinitionId, String newName) {
        try {
            // 获取原流程定义的XML
            String xmlContent = getProcessDefinitionXml(processDefinitionId);
            
            // 修改XML中的流程定义ID和名称
            xmlContent = xmlContent.replaceAll("id=\"[^\"]*\"", "id=\"" + newName + "\"")
                                  .replaceAll("name=\"[^\"]*\"", "name=\"" + newName + "\"");
            
            // 部署新的流程定义
            return deployProcessByXml(newName, xmlContent);
        } catch (Exception e) {
            logger.error("复制工作流失败", e);
            throw new RuntimeException("复制工作流失败: " + e.getMessage());
        }
    }
}